package com.hhf.rpc.core.fault.loadbalancer.impl;

import cn.hutool.core.collection.CollUtil;
import com.hhf.rpc.core.fault.loadbalancer.LoadBalancer;
import com.hhf.rpc.core.model.ServiceMetaInfo;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author hhf
 * @Date 2024/10/20
 * @Description 轮询负载均衡
 */
@Slf4j
public class RoundRobinLoadBalancer implements LoadBalancer {

    /**
     * 当前轮询的下标
     * 使用AtomicInteger保证了原子性
     * 在多线程环境下,多个线程同时对currentIndex进行自增操作，可能会导致数据不一致的情况
     */
    private final AtomicInteger currentIndex = new AtomicInteger(0);

    @Override
    public ServiceMetaInfo select(Map<String, Object> requestParams, List<ServiceMetaInfo> serviceMetaInfoList) {

        if (CollUtil.isEmpty(serviceMetaInfoList)){
            return null;
        }
        int size = serviceMetaInfoList.size();
        if (size == 1){
            ServiceMetaInfo serviceMetaInfo = serviceMetaInfoList.get(0);
            log.info("负载均衡选择服务:{}",serviceMetaInfo);
            return serviceMetaInfo;
        }
        //取模算法轮询
        int index = currentIndex.getAndIncrement() % size;
        ServiceMetaInfo serviceMetaInfo = serviceMetaInfoList.get(index);
        log.info("负载均衡选择服务:{}",serviceMetaInfo);
        return serviceMetaInfo;
    }
}
